﻿using SkiaSharp;
using SkiaSharp.Views.WPF;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WPFSkiaDragDemo
{
    /// <summary>
    /// 拖曳 
    /// </summary>
    public class Drag
    {
        public SKPoint centerPoint;
        public int Radius = 0;
        private bool Pressed = false;
        private bool CirclePressend = false;
        private SKPoint MousePoint = SKPoint.Empty;
        private SKPoint sKPoint = SKPoint.Empty;
        private SKPoint CirclePoint = SKPoint.Empty;
        private SKCanvas skCanvas;
        private SKElement skElement;
        private float dx = 0;
        private float dy = 0;
        // 存储交互区域
        public List<InteractiveArea> interactiveAreas = new List<InteractiveArea>();
        private Canvas PrenCanvas;

        //缩放情况
        public  float scaleX = 1.0f;
        public  float scaleY = 1.0f;
        public Control? currentInputControl; // 跟踪当前输入控件（TextBox或者comboBox）
        public Button? currentSwitchButton; // 跟踪当前的切换按钮
        private readonly string[] outputDescriptions = { "逻辑输出", "电源接触器", "星形接触器", "三角接触器" };
        private readonly string[] inputDescriptions = { "逻辑输入比较长", "启动按钮", "停止按钮" };
       
        public class InteractiveArea
        {
            public SKRect Rect { get; set; }
            public string Name { get; set; } = string.Empty;
            public string Type { get; set; } = string.Empty;// 表示是输出、输入还是状态块
            public Action<SKRect>? OnClick { get; set; }
        }
        /// <summary>
        /// 图元模板（侧边栏用）
        /// </summary>
        public class PrimitiveTemplate
        {
            public string Name { get; set; }
            public SKPath Path { get; set; }
            public SKPaint Paint { get; set; }

            public ElementInfo ElementInfo { get; set; } = new ElementInfo();
        }

        /// <summary>
        /// 画布上的图元
        /// </summary>
        public class CanvasPrimitive
        {
            public SKPath Path { get; set; }
            public SKPaint Paint { get; set; }
            public SKPoint Position { get; set; }
            public ElementInfo ElementInfo { get; set; } = new ElementInfo();
            // 检查点是否在图元范围内
            public bool ContainsPoint(SKPoint point)
            {
                var bounds = Path.Bounds;// 获取图元的边界矩形
                var translatedBounds = new SKRect(
                    Position.X + bounds.Left,
                    Position.Y + bounds.Top,
                    Position.X + bounds.Right,
                    Position.Y + bounds.Bottom);
                return translatedBounds.Contains(point);
            }

        }

        // 存储画布上的图元
        private List<CanvasPrimitive> CanvasPrimitives = new List<CanvasPrimitive>();
        private PrimitiveTemplate DraggedTemplate = null; // 当前拖拽的模板
        public CanvasPrimitive SelectedPrimitive = null; // 当前选中的画布图元
        private SKPoint DragPreviewPosition; // 拖拽预览位置

        public List<PrimitiveTemplate> SidebarPrimitives { get; private set; }

        /// <summary>
        /// 侧边栏模板列表
        /// </summary>
        public Drag()
        {
            SidebarPrimitives = new List<PrimitiveTemplate>
            {
                new PrimitiveTemplate
                {
                    Name = "Circle",
                    Path = new SKPath(),
                    Paint = new SKPaint { Color = SKColors.Blue, Style = SKPaintStyle.Fill }
                },
                new PrimitiveTemplate
                {
                    Name = "Rectangle",
                    Path = SKPath.ParseSvgPathData("M0,0 H50 V50 H0 Z"),
                    Paint = new SKPaint { Color = SKColors.Red, Style = SKPaintStyle.Fill }
                },
                new PrimitiveTemplate
                {
                    Name = "FB",
                    Path= SKPath.ParseSvgPathData("M0,0 H50 V50 H0 Z"),
                    Paint=new SKPaint{
                        Color = SKColors.Green,
                        Style = SKPaintStyle.Fill },
                    ElementInfo = new ElementInfo
                    {
                        Name = "电机星三角控制启动",
                        ElementType = ElementType.FB,
                        DataBindInfos = new List<DataBindInfo>
                        {
                            new DataBindInfo { Name = "FB1", BindType = DataBindType.OPERAND, Symbol="????" },
                            new DataBindInfo { Name = "START1", BindType = DataBindType.IN, Symbol="????" },
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "POWER", BindType = DataBindType.IN, Symbol="????"},
                            new DataBindInfo { Name = "TRIANGLE1", BindType = DataBindType.IN, Symbol="????" },
                            new DataBindInfo { Name = "inOUTA", BindType = DataBindType.INOUT, Symbol="????" },
                            new DataBindInfo { Name = "INOUTB", BindType = DataBindType.INOUT, Symbol="????" },
                            new DataBindInfo { Name = "POWERA", BindType = DataBindType.OUT, Symbol="????" },
                            new DataBindInfo { Name = "POWERB", BindType = DataBindType.OUT, Symbol="????" },
                            new DataBindInfo { Name = "POWERC", BindType = DataBindType.OUT, Symbol="????" },
                        }   
                    }
                },
            };
            SidebarPrimitives[0].Path.AddCircle(0, 0, 25); // 初始化圆形路径
        }
        /// <summary>
        /// 渲染
        /// </summary>
        public void Render(Canvas parentCanvas,SKCanvas skcanvas,SKElement skElement, SKTypeface Font, int Width, int Height)
        {
            this.PrenCanvas= parentCanvas;
            this.skCanvas = skcanvas;
            this.skElement = skElement;
            this.scaleX = (float)(parentCanvas.ActualWidth / skElement.ActualWidth);
            this.scaleY = (float)(parentCanvas.ActualHeight / skElement.ActualHeight);
            // 清空交互区域列表
            interactiveAreas.Clear();
            centerPoint = new SKPoint(Width / 2, Height / 2);
            this.Radius = 40;
            skCanvas.Clear(SKColors.White);
            if (CirclePoint.IsEmpty)
            {
                CirclePoint = new SKPoint(centerPoint.X, centerPoint.Y);
            }
            // 绘制所有画布上的图元
            foreach (var primitive in CanvasPrimitives)
            {
                skCanvas.Save();
                if(primitive.ElementInfo!=null && primitive.ElementInfo.ElementType == ElementType.FB)//FB类型的图元
                {
                    primitive.Paint.Color = SKColors.Green;
                    DrawFB(skCanvas, primitive);
                }
                else
                {
                    skCanvas.Translate(primitive.Position.X, primitive.Position.Y);
                    skCanvas.DrawPath(primitive.Path, primitive.Paint);
                }

                skCanvas.Restore();
            }
            if (CirclePressend)
            {
                CirclePoint = new SKPoint(sKPoint.X - dx, sKPoint.Y - dy);
                DrawCircle(this.skCanvas, CirclePoint);
            }
            else
            {
                DrawCircle(this.skCanvas, CirclePoint);
            }
            if (DraggedTemplate != null)
            {
                using var previewPaint = new SKPaint
                {
                    Color = DraggedTemplate.Paint.Color.WithAlpha(128), // 半透明
                    Style = DraggedTemplate.Paint.Style
                };
                skCanvas.Save();
                if (DraggedTemplate.ElementInfo != null && DraggedTemplate.ElementInfo.ElementType == ElementType.FB)
                {
                    CanvasPrimitive DraggedTemplateFB = new CanvasPrimitive
                    {
                        Path = new SKPath(DraggedTemplate.Path),
                        Paint = new SKPaint { Color = DraggedTemplate.Paint.Color, Style = DraggedTemplate.Paint.Style },
                        Position = DragPreviewPosition,
                        ElementInfo = DraggedTemplate.ElementInfo
                    };
                    DrawFB(skCanvas, DraggedTemplateFB);
                }
                else {
                    skCanvas.Translate(DragPreviewPosition.X, DragPreviewPosition.Y);
                    skCanvas.DrawPath(DraggedTemplate.Path, previewPaint);
                }

                skCanvas.Restore();
            }
            using var paint = new SKPaint
            {
                Color = SKColors.Black,
                IsAntialias = true,
                Typeface = Font,
                TextSize = 24
            };
            using var paint2 = new SKPaint
            {
                Color = SKColors.Blue,
                IsAntialias = true,
                Typeface = Font,
                TextSize = 24
            };
            var msg = $"X:{sKPoint.X}  Y:{sKPoint.Y}  Pressed:{Pressed} CirclePressend:{CirclePressend}";
            using var font = new SKFont(Font, 24);

            skCanvas.DrawText(msg, 0, 30, paint);


            // DrawCircle(this.skCanvas, new SKPoint(400,200));
            // 创建一个画笔，用于绘制边框

            using var paint3 = new SKPaint
            {

                Color = SKColors.Black,// 边框颜色
                StrokeWidth = 5,       // 边框宽度
                IsStroke = true,  // 设置为绘制轮廓
                IsAntialias = true,  // 抗锯齿
            };
          //  canvas.DrawRect(0, 0, Width, Height, paint3);

        }
        public void StartDrag(PrimitiveTemplate template, SKPoint startPoint)
        {
            DraggedTemplate = template;
            DragPreviewPosition = startPoint;
            SelectedPrimitive = null; // 清除选中状态
        }
        public void UpdateDrag(SKPoint point)
        {
            if (DraggedTemplate != null)
            {
                DragPreviewPosition = point;
            }
            else if (SelectedPrimitive != null)
            {
                SelectedPrimitive.Position = point;
            }
        }
        public void EndDrag(SKPoint dropPoint)
        {
            if (DraggedTemplate != null)
            {
                var newPrimitive = new CanvasPrimitive
                {
                    Path = new SKPath(DraggedTemplate.Path),
                    Paint = new SKPaint { Color = DraggedTemplate.Paint.Color, Style = DraggedTemplate.Paint.Style },
                    Position = dropPoint,
                    ElementInfo=DraggedTemplate.ElementInfo
                };
                CanvasPrimitives.Add(newPrimitive);
                DraggedTemplate = null;
            }
            SelectedPrimitive = null; // 结束移动
        }
        public void SelectPrimitive(SKPoint point)
        {
            foreach (var primitive in CanvasPrimitives)
            {
                if (primitive.ContainsPoint(point))
                {
                    SelectedPrimitive = primitive;
                    return;
                }
            }
            SelectedPrimitive = null;
        }
        public void MouseMove(SKPoint sKPoint)
        {
            MousePoint = sKPoint;
            this.sKPoint = sKPoint;
            if (CirclePressend)//按下，就开始拖动
            {
                CirclePoint = sKPoint;
            }
            if (DraggedTemplate != null)
            {
                DragPreviewPosition = new SKPoint(sKPoint.X - dx, sKPoint.Y - dy);
            }
        }
        public void MouseDown(SKPoint sKPoint, bool Pressed)
        {
            MousePoint = sKPoint;
            this.sKPoint = sKPoint;
            this.Pressed = Pressed;
            if (this.Pressed)
            {
                this.CirclePressend = CheckPoint(sKPoint, CirclePoint);
                if (this.CirclePressend)
                {
                    dx = sKPoint.X - CirclePoint.X;
                    dy = sKPoint.Y - CirclePoint.Y;
                }
            }
            else
            {
                this.CirclePressend = false;
            }
        }
        public void StartDragFromSidebar(PrimitiveTemplate template, SKPoint startPoint)
        {
            DraggedTemplate = template;
            MousePoint = startPoint;
            dx = 25; // 假设图元中心偏移
            dy = 25;
        }
        public void DropOnCanvas(SKPoint dropPoint)
        {
            if (DraggedTemplate != null)
            {
                var newPrimitive = new CanvasPrimitive
                {
                    Path = new SKPath(DraggedTemplate.Path),
                    Paint = new SKPaint { Color = DraggedTemplate.Paint.Color, Style = DraggedTemplate.Paint.Style },
                    Position = new SKPoint(dropPoint.X - dx, dropPoint.Y - dy),
                    ElementInfo = DraggedTemplate.ElementInfo
                };
                CanvasPrimitives.Add(newPrimitive);
                DraggedTemplate = null;
            }
        }
        
        public bool CheckPoint(SKPoint sKPoint, SKPoint CirclePoint)
        {
            var d = Math.Sqrt(Math.Pow(sKPoint.X - CirclePoint.X, 2) + Math.Pow(sKPoint.Y - CirclePoint.Y, 2));
            return d <= this.Radius;
        }
        /// <summary>
        /// 画一个圆
        /// </summary>
        public void DrawCircle(SKCanvas canvas, SKPoint sKPoint)
        {
            using var paint = new SKPaint
            {
                Color = SKColors.Blue,
                Style = SKPaintStyle.Fill,
                IsAntialias = true,
                StrokeWidth = 2
            };
            canvas.DrawCircle(sKPoint.X, sKPoint.Y, Radius, paint);
        }
        public void DrawFB(SKCanvas canvas, CanvasPrimitive canvasPrimitive)
        {
            // 定义矩形框的尺寸和位置
            float margin = 50;
            float boxWidth = 300 - 2 * margin;
            float boxHeight = 120+canvasPrimitive.ElementInfo.GetMaxHight()*40; // 调整高度以适应内容
            float boxX = canvasPrimitive.Position.X;
            float boxY = canvasPrimitive.Position.Y;
            // 创建支持中文的字体
            using (var typeface = SKTypeface.FromFamilyName("Microsoft YaHei", SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright))
            {
                using (var paint = new SKPaint())
                {
                    paint.Style = SKPaintStyle.Stroke;
                    paint.Color = SKColors.Blue;
                    paint.StrokeWidth = 2;
                    canvas.DrawRect(boxX, boxY, boxWidth, boxHeight, paint);
                }

                // 绘制模块名和功能块标题
                using (var paint = new SKPaint())
                {
                    paint.Color = SKColors.Black;
                    paint.IsAntialias = true;
                    paint.Typeface = typeface;

                    // 模块名 %FC1,操作数
                    paint.TextSize = 14;
                    canvas.DrawText(canvasPrimitive.ElementInfo.GetDataBindOPERAND()?.Symbol??"????", boxX + 100, boxY + 20, paint);

                    // 标题：电机星三角控制启动
                    paint.TextSize = 16;
                    float titleWidth = paint.MeasureText(canvasPrimitive.ElementInfo.Name);
                    canvas.DrawText(canvasPrimitive.ElementInfo.Name, boxX + (boxWidth - titleWidth) / 2, boxY + 40, paint);
                }

                // 绘制状态块（不显示列名）

                float startY = boxY + 60;


                // 绘制左侧输入信号
                using (var paint = new SKPaint())
                {
                    paint.Color = SKColors.Black;
                    paint.TextSize = 12;
                    paint.IsAntialias = true;
                    paint.StrokeWidth = 1;
                    paint.Typeface = typeface;


                    List<DataBindInfo> listIN_INOUT = new List<DataBindInfo>();
                    listIN_INOUT.AddRange(canvasPrimitive.ElementInfo.GetIN());
                    listIN_INOUT.AddRange(canvasPrimitive.ElementInfo.GetINOUT());
                    for (int i = 0; i < listIN_INOUT.Count; ++i)
                    {


                        float y = startY + 30 + i * 40;

                        // 框内标签
                        string inputText = listIN_INOUT[i].Name;

                        canvas.DrawText(inputText, boxX + 10, y, paint);

                        // 绘制连接线
                        canvas.DrawLine(boxX - 30, y - 5, boxX, y - 5, paint);


                        // 输入标签和描述
                        string internalLabel = listIN_INOUT[i].Symbol??"???";
                        float inputTextWidth = paint.MeasureText(internalLabel);
                        float leftTop = boxX - inputTextWidth - 30;
                        canvas.DrawText(internalLabel, leftTop, y, paint);

                        // 添加交互区域（输入标签）
                        var inputRect = SKRect.Create(leftTop, y - 15, inputTextWidth, 20);
                        interactiveAreas.Add(new InteractiveArea
                        {
                            Rect = inputRect,
                            Name = inputText,
                            Type = "Input",
                            //OnClick = inputRect => MessageBox.Show($"Clicked on input: {inputText}")
                            OnClick = inputRect => CreateInputControl(inputRect, internalLabel, "Input")
                        });
                    }
                }

                // 绘制右侧输出信号
                using (var paint = new SKPaint())
                {
                    paint.Color = SKColors.Black;
                    paint.TextSize = 12;
                    paint.IsAntialias = true;
                    paint.StrokeWidth = 1;
                    paint.Typeface = typeface;
                    List<DataBindInfo> listOUT = canvasPrimitive.ElementInfo.GetOUT();
                    // 定义右侧对齐的参考点
                    float rightAlignX = boxX + boxWidth; // 右侧对齐的 x 坐标
                    for (int i = 0; i < listOUT.Count; i++)
                    {
                        float y = startY + 30 + i * 40;
                        // 框内标签（M1.0、M1.1、M1.2）
                        string internalLabel = listOUT[i].Name;
                        float textWidth = 0;
                        if (!string.IsNullOrEmpty(internalLabel))
                        {
                            textWidth = paint.MeasureText(internalLabel); //字占的长度

                            canvas.DrawText(internalLabel, rightAlignX - textWidth, y, paint);//右对齐
                        }

                        // 绘制连接线
                        canvas.DrawLine(boxX + boxWidth, y - 5, boxX + boxWidth + 30, y - 5, paint);

                        // 输出标签和描述
                        string outputText = listOUT[i].Symbol??"????";
                        float lefttop = boxX + boxWidth + 30;
                        float desTextWidth = paint.MeasureText(outputText); //字占的长度
                        canvas.DrawText(outputText, lefttop, y, paint);

                        // 添加交互区域（输出标签）
                        var outputRect = SKRect.Create(lefttop, y - 15, desTextWidth, 20);
                        interactiveAreas.Add(new InteractiveArea
                        {
                            Rect = outputRect,
                            Name = outputText,
                            Type = "Output",
                            //OnClick = () => MessageBox.Show($"Clicked on output: {outputText}")
                            OnClick = outputRect => CreateInputControl(outputRect, outputText, "Output")
                        });
                    }
                }
            }
            // 绘制矩形框

            // 绘制左右两侧的外部连接线
            using (var paint = new SKPaint())
            {
                paint.Color = SKColors.Black;
                paint.StrokeWidth = 1;

                // 左侧线
                canvas.DrawLine(margin - 20, boxY, margin - 20, boxY + boxHeight, paint);

            }
            // 绘制交互区域的蓝色边框（用于调试）
            using (var debugPaint = new SKPaint())
            {
                debugPaint.Style = SKPaintStyle.Stroke;
                debugPaint.Color = SKColors.Blue;
                debugPaint.StrokeWidth = 1;

                foreach (var area in interactiveAreas)
                {
                    canvas.DrawRect(area.Rect, debugPaint);
                }
            }
        }

        private void CreateInputControl(SKRect rect, string initialValue, string type)
        {
            // 转换到 WPF 逻辑坐标
            var scale = VisualTreeHelper.GetDpi(this.skElement).DpiScaleX;
            double x = rect.Left / scale;
            double y = rect.Top / scale;
            double width = rect.Width / scale;
            double height = rect.Height / scale;

            // 创建 TextBox
            var textBox = new TextBox
            {
                Text = initialValue,
                Width = width,
                Height = height,
                Margin = new Thickness(x, y, 0, 0)
            };

            // 创建切换按钮
            var switchButton = new Button
            {
                Content = "▼",
                Width = 20,
                Height = height,
                Margin = new Thickness(x + width, y, 0, 0)
            };
            switchButton.Click += (s, e) => SwitchToComboBox(rect, initialValue, type);

            // 添加到父容器
            PrenCanvas.Children.Add(textBox);
            PrenCanvas.Children.Add(switchButton);
            currentInputControl = textBox;
            currentSwitchButton = switchButton; // 跟踪切换按钮
            // 绑定 TextBox 的 LostFocus 事件，更新数据
            textBox.LostFocus += (s, e) =>
            {
                UpdateValue(textBox.Text, type, initialValue);
                PrenCanvas.Children.Remove(textBox);
                PrenCanvas.Children.Remove(switchButton);
                currentInputControl = null;
                currentSwitchButton = null;
                skElement.InvalidateVisual();
            };
        }
        private void SwitchToComboBox(SKRect rect, string initialValue, string type)
        {
            if (currentInputControl != null)
            {
                PrenCanvas.Children.Remove(currentInputControl);
            }
            if (currentSwitchButton != null)
            {
                PrenCanvas.Children.Remove(currentSwitchButton);
                currentSwitchButton = null;
            }

            // 转换到 WPF 逻辑坐标
            var scale = VisualTreeHelper.GetDpi(this.skElement).DpiScaleX;
            double x = rect.Left / scale;
            double y = rect.Top / scale;
            double width = rect.Width / scale;
            double height = rect.Height / scale;

            // 创建 ComboBox
            var comboBox = new ComboBox
            {
                Width = width,
                Height = height,
                Margin = new Thickness(x, y, 0, 0),
                ItemsSource = GetOptions(type, initialValue),
                SelectedItem = initialValue
            };

            // 添加到父容器
            PrenCanvas.Children.Add(comboBox);
            currentInputControl = comboBox;

            // 绑定 ComboBox 的 SelectionChanged 事件，更新数据
            comboBox.SelectionChanged += (s, e) =>
            {
                if (comboBox.SelectedItem != null)
                {
                    UpdateValue(comboBox.SelectedItem.ToString(), type, initialValue);
                    PrenCanvas.Children.Remove(comboBox);
                    currentInputControl = null;
                    skElement.InvalidateVisual();
                }
            };
        }
        private void UpdateValue(string newValue, string type, string oldValue)
        {
            // 更新对应的数据
            ///TODO!!后面再加
            switch (type)
            {
                case "Input":
                    int inputIndex = Array.IndexOf(inputDescriptions, oldValue.Split(' ')[0]) >= 0 ? Array.IndexOf(inputDescriptions, oldValue.Split(' ')[0]) : -1;
                    if (inputIndex >= 0 && inputIndex < inputDescriptions.Length)
                        inputDescriptions[inputIndex] = newValue.Split(' ')[0];
                    break;
                case "Output":
                    int outputIndex = Array.IndexOf(outputDescriptions, oldValue.Split(' ')[0]) >= 0 ? Array.IndexOf(outputDescriptions, oldValue.Split(' ')[0]) : -1;
                    if (outputIndex >= 0 && outputIndex < outputDescriptions.Length)
                        outputDescriptions[outputIndex] = newValue.Split(' ')[0];
                    break;
            }
        }
        private List<string> GetOptions(string type, string initialValue)
        {
            // 根据类型返回不同的选项
            switch (type)
            {
                case "Input":
                    return new List<string> { "逻辑输入比较长", "启动按钮", "停止按钮" };
                case "Output":
                    return new List<string> { "逻辑输出", "电源接触器", "星形接触器", "三角接触器" };
                default:
                    return new List<string> { initialValue };
            }
        }
    }
}
